package com.ems.remote.components;

import com.ems.bo.FrameBo;
import com.ems.remote.IStrategy;
import com.ems.service.IDeviceService;
import com.ems.util.ChannelMap;
import com.ems.util.EmsCRC8;
import com.ems.util.HexUtil;
import com.ems.vo.DeviceVo;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Author: Wuzh
 * @Description:
 * @Date Created in 22:38 2023-12-19
 * @return
 */
@Component
@Slf4j
public class LoginStrategy implements IStrategy {

    @Resource
    private IDeviceService iDeviceService;

    /**
     * 解析登录帧数据：01 66 73 6a 79 23 25 40 32 30 31 36
     *
     * @param frameBo：解析后的帧数据内容
     * @param ctx
     * @return
     */
    @Override
    public void action ( FrameBo frameBo, ChannelHandlerContext ctx ) {
        log.info ( "设备地址->{}, 登录数据->{}", frameBo.getDeviceAddress (), frameBo.getData () );
        //1.解析用户名和密码:0c000e05045601666569736a7923254032303136ee0d
        String s = HexUtil.parseData ( frameBo.getData (), 1, frameBo.getData ().length () / 2 );
        String userNameAndPass = HexUtil.hexToUtf8 ( s );
        String[] split = userNameAndPass.split ( "#%" );
        DeviceVo deviceVo = new DeviceVo ();
        deviceVo.setUserName ( split[0] );
        deviceVo.setPassword ( split[1] );
        deviceVo.setDeviceAddress ( String.valueOf ( HexUtil.hexToDecimal ( frameBo.getDeviceAddress (), 0, 2 ) ) );
        DeviceVo vo = iDeviceService.querySingle ( deviceVo );
        if ( vo == null ) {
            iDeviceService.saveSingle ( deviceVo );
        }
        //存入Netty通道
        ChannelMap.getChannelMap ().put ( frameBo.getDeviceAddress (), ctx.channel () );
        //响应
        response ( frameBo );
    }

    /**
     * 登录认证应答
     */
    public void response ( FrameBo frameBo ) {
        Channel channel = ChannelMap.getChannel ( frameBo.getDeviceAddress () );
        log.info ( "获取channel->{}", channel );
        if ( channel == null ) {
            // 重启机器....
        }
        //校验码=长度到数据最后字节
        //00 02 09 00 01 05 01
        log.info ( "[{}, {}]", frameBo.getDeviceAddressHigh (), frameBo.getDeviceAddressLow () );
        byte[] bytes = {0x00, 0x02, 0x09, frameBo.getDeviceAddressHigh (), frameBo.getDeviceAddressLow (), 0x05, 0x01};
        byte crc = EmsCRC8.emsCrc ( bytes, 7 );
        log.info ( "crc->{}", crc );
        //响应数据
        byte[] re = {0x0c, 0x00, 0x02, 0x09, frameBo.getDeviceAddressHigh (), frameBo.getDeviceAddressLow (), 0x05, 0x01, crc, 0x0d};
        log.info ( "响应数据->{}", re );
        channel.writeAndFlush ( re );
    }

}
